home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-01-16 | 13.0 KB | 402 lines | [TEXT/ttxt] |
- // Listing 1. MyPart::Draw, simplest case
- void MyPart::Draw(Environment* ev, ODFacet* facet, ODShape* invalShape)
- {
- // Set up graphics port.
- GrafPtr port = facet->GetCanvas(ev)->GetQDPort(ev);
- SetPort(port);
-
- // Set up graphics port offset for drawing content.
- ODTransform* localToGlobal = facet->GetContentTransform(ev, kODNULL);
- ODPoint offset(0,0);
- offset = localToGlobal->TransformPoint(ev, &offset);
- SetOrigin(-offset.IntX(), -offset.IntY());
- localToGlobal->Release(ev);
-
- // Set up graphics port clip; save old clip.
- RgnHandle saveClip = NewRgn();
- GetClip(saveClip);
- ODShape* clipShape = facet->GetAggregateClipShape(ev, kODNULL);
- RgnHandle clip = clipShape->GetQDRegion(ev);
- SetClip(clip);
- clipShape->Release(ev);
-
- // And draw (insert your drawing code here).
- // Remember to respect the scaling and rotation information
- // in your content transform, if possible. If you can't do this,
- // it's graceful to at least try to draw as best you can, rather
- // than simply signaling an error.
- ...
-
- // Clean up.
- SetClip(saveClip);
- DisposeRgn(saveClip);
- SetOrigin(0,0);
- }
-
- // Listing 2. MyPart::Draw, with scrolling
- void MyPart::Draw(Environment* ev, ODFacet* facet, ODShape* invalShape)
- {
- Point spclOffset = {0,0};
- Point contentOffset = {0,0};
-
- // Set up graphics port.
- GrafPtr port = facet->GetCanvas(ev)->GetQDPort(ev);
- SetPort(port);
-
- // Set up graphics port offsets for controls.
- ODTransform* localToGlobal = facet->GetFrameTransform(ev, kODNULL);
- ODPoint tempOffset1(0,0);
- tempOffset1 = localToGlobal->TransformPoint(ev, &tempOffset1);
- SetOrigin(-tempOffset1.IntX(), -tempOffset1.IntY());
-
- // Set up special offset for later efficient reset of clipping region.
- spclOffset = localToGlobal->GetQDOffset(ev);
- ODTransform* contentTransform = facet->GetContentTransform(ev,
- kODNULL);
- contentOffset = contentTransform->GetQDOffset(ev);
- spclOffset.v -= contentOffset.v; spclOffset.h -= contentOffset.h;
- localToGlobal->Release(ev);
-
- // Set up graphics port clipping.
- RgnHandle saveClip = NewRgn();
- GetClip(saveClip);
- ODShape* clipShape = facet->GetAggregateClipShape(ev, kODNULL);
- RgnHandle clip = clipShape->GetQDRegion(ev);
- SetClip(clip);
-
- // Draw your controls (such as scroll bars) here, using the standard
- // Toolbox calls. Remember to respect the scaling and rotation
- // information in your transform, or at least try to draw as best
- // you can, rather than simply signaling an error.
- ...
-
- // Set up graphics port for drawing content.
- ODPoint tempOffset2(0,0);
- tempOffset2 = contentTransform->TransformPoint(ev, &tempOffset2);
- SetOrigin(-tempOffset2.IntX(), -tempOffset2.IntY());
-
- // Use the special offset we set up earlier to keep the clip in the
- // right place relative to the origin. Remember to remove the scroll
- // bar area from the clipping region.
- OffsetRgn(clip, spclOffset.h, spclOffset.v);
- SetClip(clip);
-
- // And draw (insert your drawing code here).
- // Remember to respect the scaling and rotation information
- // in your content transform if possible, as mentioned above.
- ...
-
- // Clean up.
- SetClip(saveClip);
- DisposeRgn(saveClip);
- contentTransform->Release(ev);
- clipShape->Release(ev);
- SetOrigin(0, 0);
- }
-
- // Listing 3. Handling the scrolling
- ODBoolean MyPart::HandleMouseDownScrollBar(Environment* ev, Point mouse,
- ODFrame* frame)
- {
- ODSShort partcode = TrackControl(fScrollBar, mouse, kODNULL);
- Point transPt;
- ODSShort setting = GetControlValue(fScrollBar);
-
- if (partcode) {
- // Deal with the scroll bar and choose the scroll distance.
- switch (partcode) {
- case inUpButton:
- setting--;
- break;
- case inDownButton:
- setting++;
- break;
- case inPageUp:
- if ((setting - kPBPageSize) < 0) setting = 0;
- else setting -= kPBPageSize;
- break;
- case inPageDown:
- ODSShort max = GetControlMaximum(fScrollBar);
- if ((setting + kPBPageSize) > max) setting = max;
- else setting += kPBPageSize;
- break;
- default:
- break;
- }
-
- SetControlValue(fScrollBar, setting);
- SetPt(&transPt, 0, (0-setting)); // This is a vertical
- // scroll bar.
-
- // Set up the transform.
- ODTransform* newIntTrans = frame->CreateTransform(ev);
- newIntTrans->SetQDOffset(ev, &transPt);
- frame->ChangeInternalTransform(ev, newIntTrans, kODNULL);
- newIntTrans->Release(ev);
-
- // Here's some simplified code for invalidating any embedded
- // facets that have been moved. This is a "saturation bombing"
- // approach rather than the tuned code of a real application,
- // but it gets the basic idea across. Typically, we do a
- // ScrollRect followed by invalidation of the revealed area.
- // Here we simply invalidate everything.
- frame->Invalidate(ev, kODNULL, kODNULL);
- return kODTrue;
- }
- return kODFalse;
- }
-
-
- // Listing 4. A 4x scaling operation
- void MyPart::ZoomContents4X(Environment* ev, ODFrame* frame)
- {
- ODPoint frameScale(4, 4);
-
- // Apply the zoom transformation.
- ODTransform* intTrans = frame->GetInternalTransform(ev, kODNULL);
- intTrans->ScaleBy(ev, &frameScale);
- intTrans->Release(ev);
-
- // Invalidate the frame for redrawing.
- frame->Invalidate(ev, kODNULL, kODNULL);
- }
-
- // Listing 5. Making an embedded part visible
- void MyPart::EmbedPartFromSU(Environment* ev, ODStorageUnit* newSU,
- ODFacet* myFacet)
- {
- ODPart* newPart = newSU->GetDraft(ev)->GetPart(ev, newPartID);
- ODRect rect(0, 0, kPBDefaultFrameSize, kPBDefaultFrameSize);
- ODShape* newFrameShape = myFacet->CreateShape(ev);
- newFrameShape->SetRectangle(ev, &rect);
- ODFrame* newFrame = newSU->GetDraft(ev)->CreateFrame(ev,
- kODNULL, // Use the default frame type.
- myFacet->GetFrame(ev), // Containing frame is my frame.
- newFrameShape, // Use the frame shape we set up.
- (ODCanvas*)kODNULL, // No special canvas.
- newPart, // The part in the frame.
- fSession->Tokenize(ev, kODViewAsFrame), // View as a frame.
- kODNullTypeToken, // Undefined presentation.
- kODFalse, // Not a root frame.
- kODFalse); // Not overlaid.
- newSU->Release(ev);
- // Set up a clip shape, same as frame shape.
- ODShape* frameShape = newFrame->GetFrameShape(ev, kODNULL);
- ODShape* newClipShape = frameShape->Copy(ev);
- Point offset = {100,100};
- ODTransform* newExternalXForm = myFacet->CreateTransform(ev);
- newExternalXForm->SetQDOffset(ev, &offset);
- ODFacet* newFacet = myFacet->CreateEmbeddedFacet(ev,
- newFrame, // Of this frame.
- newClipShape, // With this clip shape.
- newExternalXForm, // At this location/scale/rotation.
- kODNULL, // No special canvas.
- kODNULL, // No special bias canvas.
- kODNULL, // No sibling specified.
- kODFrameInFront); // Put this facet at front.
-
- // At this point, we probably want to remember the new frame
- // and facet in some data structure.
- this->rememberFrame(newFrame, newFacet);
-
- // Invalidate facet so that it displays. We need to invalidate our
- // entire frame because the new facet may interact with other content
- // in various ways. This is the simplest correct method, although
- // optimizations may be reasonable in production code.
- myFacet->GetFrame(ev)->Invalidate(ev, kODNULL, kODNULL);
-
- // Clean up.
- newPart->Release(ev);
- newFrame->Release(ev);
- newFrameShape->Release(ev);
- newExternalXForm->Release(ev);
- newClipShape->Release(ev);
- frameShape->Release(ev);
- }
-
-
- // Listing 6. Altering the coordinate system scaling
- void MyPart::ShiftCoordinateScaling(Environment* ev, ODFrame* frame)
- {
- ODPoint frameScale(72,72);
-
- // Set up the transform.
- ODTransform* existingTransform = frame->GetInternalTransform(ev,
- kODNULL);
- ODTransform* newIntTrans = existingTransform->Copy(ev);
- existingTransform->Release(ev);
- newIntTrans->ScaleDownBy(ev, &frameScale);
-
- // Apply the zoom transformation within myself.
- frame->ChangeInternalTransform(ev, newIntTrans, kODNULL);
- newIntTrans->Release(ev);
-
- // Now, be a good citizen and iterate over every facet of myself.
- ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
- for (ODFacet* facet = facets->First(ev); facets->IsNotComplete(ev);
- facet = facets->Next(ev)) {
- // For each facet of myself, find every embedded facet.
- ODFacetIterator* embeddedFacets = facet->CreateFacetIterator(ev,
- kODTopDown, kODFrontToBack);
- for (ODFacet* embeddedFacet = embeddedFacets->First(ev);
- embeddedFacets->IsNotComplete(ev);
- embeddedFacet = embeddedFacets->Next(ev)) {
- // Alter the transform of each embedded facet.
- existingTransform = embeddedFacet->GetExternalTransform(ev,
- kODNULL);
- ODTransform* newExtTrans = existingTransform->Copy(ev);
- // Notice that we scale in the opposite direction in
- // each embedded frame.
- newExtTrans->ScaleBy(ev, &frameScale);
- embeddedFacet->ChangeGeometry(ev, kODNULL, newExtTrans,
- kODNULL);
- newExtTrans->Release(ev);
- existingTransform->Release(ev);
- }
- ODDeleteObject(embeddedFacets);
- }
- ODDeleteObject(facets);
- }
-
- // Listing 7. Setting clipping when printing to a PostScript device
- #define kPostScriptBegin 190 // Picture comments for PostScript
- #define kPostScriptEnd 191 // printing.
- #define kPostScriptHandle 192
-
- void ODBeginPostScriptClip(Environment* ev, ODShape *shape)
- {
- ODPolygon poly = shape->CopyPolygon(ev);
- Handle clipHandle = NewEmptyHandle();
-
- AppendString("\pgrestore", clipHandle); // Utility routine to append
- AppendString("\pnewpath", clipHandle); // string to a handle.
-
- char buf[128];
- ODContour *cont = poly.FirstContour();
-
- for (long n=poly.GetNContours(); n>0; n--) {
- const ODPoint *v = cont->vertex;
- long m = cont->nVertices;
- if (m > 2) {
- sprintf(buf, "%.2f %.2f moveto", v->x/65536.0, v->y/65536.0);
- AppendBuf(buf, strlen(buf), clipHandle); // Utility routine to
- // append string buffer to a handle.
- while (--m > 0) {
- v++;
- sprintf( buf, "%.2f %.2f lineto", v->x/65536.0,
- v->y/65536.0);
- AppendBuf(buf, strlen(buf), clipHandle);
- }
- }
- AppendString("\pclosepath clip", clipHandle);
- cont = cont->NextContour();
- }
-
- // Set pic comment; then delete clipHandle.
- AppendString("\pgsave", clipHandle);
- PicComment(kPostScriptBegin, 0, kODNULL);
- PicComment(kPostScriptHandle, GetHandleSize(clipHandle), clipHandle);
- PicComment(kPostScriptEnd, 0, kODNULL);
- DisposeHandle(clipHandle);
- }
-
- void ODEndPostScriptClip( )
- {
- Handle clipHandle = NewEmptyHandle();
- AppendString("\pgrestore", clipHandle);
- PicComment(kPostScriptBegin, 0, kODNULL);
- PicComment(kPostScriptHandle, GetHandleSize(clipHandle), clipHandle);
- PicComment(kPostScriptEnd, 0, kODNULL);
- DisposeHandle(clipHandle);
- }
-
- // Listing 8. Setup for basic printing
- ODFacet* MyPart::BeginPrinting(Environment *ev, ODFrame* rootFrame,
- TPrPort* thePrPort, ODRect *pageRect)
- {
- // Set up identity transform, get page rect, set up to clip to it.
- ODTransform* xtransform = rootFrame->CreateTransform(ev);
- ODShape* clipshape = rootFrame->CreateShape(ev);
- clipshape->SetRectangle(ev, pageRect);
-
- // Create a facet with the specific geometry we just set up.
- ODFacet* prFacet = fSession->GetWindowState(ev)->
- CreateFacet(ev, rootFrame, clipshape, xtransform, kODNULL,
- kODNULL);
- xtransform->Release(ev);
- clipshape->Release(ev);
-
- // Set up a canvas based on the print job's port.
- ODCanvas* prCanvas = prFacet->CreateCanvas(ev, kODQuickDraw,
- (GrafPtr)thePrPort, kODFalse, kODFalse);
- prCanvas->SetPlatformPrintJob(ev, kODQuickDraw, (GrafPtr)thePrPort);
-
- // Make it the canvas of the facet we created.
- prFacet->SetCanvas(ev, prCanvas);
- rootFrame->FacetAdded(ev, prFacet);
-
- // Return the facet to the main print routine.
- return prFacet;
- }
-
- // Listing 9. Printing a page
- void MyPart::PrintPage(Environment *ev, ODFacet* prFacet, ODUShort page,
- ODRect *pageRect)
- {
- // Get some basic printing geometry.
- ODRect bbox;
- Rect frect, qdPRect;
-
- ODShape* frameShape = prFacet->GetFrame(ev)->
- GetFrameShape(ev, kODNULL);
- frameShape->GetBoundingBox(ev, &bbox);
- bbox.AsQDRect(frect);
- frameShape->Release(ev);
- Point pt = {0,0};
- ODUShort locator = page-1;
-
- // Pick an appropriate offset, based on page number.
- pageRect->AsQDRect(qdPRect);
- while (locator) {
- pt.v += (qdPRect.bottom+1);
- locator--;
- if (PtInRect(pt, &frect))
- continue;
- else {
- pt.v = 0; pt.h += (qdPRect.right+1);
- }
- }
-
- // Make a transform for that offset.
- ODTransform* xtransform = prFacet->CreateTransform(ev);
- xtransform->SetQDOffset(ev, &pt);
-
- // Create a clip shape for the page, based on the transform.
- ODShape* clipshape = prFacet->CreateShape(ev);
- clipshape->SetRectangle(ev, pageRect);
- ODShape* invalshape = clipshape->Copy(ev);
- clipshape->Transform(ev, xtransform);
- xtransform->Invert(ev);
-
- // Change the geometry of the printing facet.
- prFacet->ChangeGeometry(ev, clipshape, xtransform, kODNULL);
-
- // Draw everything on the page. OpenDoc will call the Draw method
- // on every part visible on the page.
- prFacet->Update(ev, invalshape, kODNULL);
-
- // Clean up.
- clipshape->Release(ev);
- invalshape->Release(ev);
- xtransform->Release(ev);
- }
-
- // Listing 10. Cleanup after printing
- void MyPart::EndPrinting(Environment *ev, ODFacet* prFacet)
- {
- // Find the printing canvas and facet; delete them.
- ODCanvas* prCanvas = prFacet->GetCanvas(ev);
- prFacet->GetFrame(ev)->FacetRemoved(ev, prFacet);
- delete prCanvas;
- delete prFacet;
- }